-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local lu = require 'luaunit'
local defs = require 'domain.defs'
local open_db = require 'lsw.db'
local ext_vlan = require 'domain.device.switch.chip.external_vlan'
local sw_chip = require 'domain.device.switch.chip.switch_chip'
local port = require 'domain.device.switch.chip.port'

TestSwitch = {}

local function construct_db()
    local ok, datas = pcall(require, 'lsw.datas')
    if not ok then
        -- 如果没有datas配置，证明当前组件不需要datas，仅打开数据库
        datas = nil
    end
    local db = open_db(':memory:', datas)
    return db
end

function TestSwitch:test_vlan()
    local db = construct_db()
    local ext_vlan_instance = ext_vlan.new({obj = {
        Unit = 1
    }}, db)
    ext_vlan_instance:set_smm_path('smm')
    local res = ext_vlan_instance:get_smm_path()
    lu.assertEquals(res, 'smm')
    ext_vlan_instance:set_external_vlanid(1)
    res = ext_vlan_instance:get_external_vlanid()
    lu.assertEquals(res, 1)

    ext_vlan_instance:set_smm_path('smm2')
    ext_vlan_instance:set_external_vlanid(2)

    ext_vlan_instance = ext_vlan.new({obj = {
        Unit = 2
    }, component = {vlans = {1, 2, 6}}}, db)
    res = ext_vlan_instance:get_smm_path()
    lu.assertEquals(res, 0)
    res = ext_vlan_instance:get_external_vlanid()
    lu.assertEquals(res, 0)
    ext_vlan_instance:set_external_vlanid(2)

    ext_vlan_instance:start_init()
end

function TestSwitch:test_vlan_init()
    local db = construct_db()
    local chip = sw_chip.new(db)
    chip:add_object({Type = 1, Unit = 1})
    local ext_vlan_instance = ext_vlan.new(chip, db)
    ext_vlan_instance:start_init()
    ext_vlan_instance:switch_smm_vlan(6)
    ext_vlan_instance:config_new_vlan(6)
    ext_vlan_instance:erase_old_vlan()
    -- 此UT发现代码问题
    ext_vlan_instance:init_external_vlan({})
    ext_vlan_instance:init_external_vlan({obj = {
        Member = 1, Untaged = 1
    }})
    local ok = pcall(ext_vlan_instance.register_signal, ext_vlan_instance)
    lu.assertEquals(ok, false)
    ok = pcall(ext_vlan_instance.try_get_external_vlan, ext_vlan_instance)
    lu.assertEquals(ok, false)
    ok = pcall(ext_vlan_instance.try_get_smm_path, ext_vlan_instance)
    lu.assertEquals(ok, false)
    ext_vlan_instance:check_vlanid_and_init_vlan(1)
end

function TestSwitch:test_port()
    local db = construct_db()
    local chip = sw_chip.new(db)
    chip:add_object({Type = 1, Unit = 1})
    local port_instance = port.new({
        Unit = 1, PhysicalId = 1, PVid = 1, AccFrameType = 1,
        PortType = 1, ConPhyAddr = 1
    }, chip)
    port_instance:vlan_init()
    port_instance:port_init()
    port_instance:port_iso()
    port_instance:port_storm()
    port_instance:start_init()
    port_instance:port_vlan_init()

    local res = port_instance:is_health()
    lu.assertEquals(res, true)

    port_instance:update_port_status()
    port_instance:update_port_auto_ngo()
    port_instance:update_port_stp_state()
    port_instance:update_port_pkt_cnt()
    port_instance:update_port_info()
    port_instance:get_port_dynamic_info()

    port_instance:get_prop('PhysicalId')
end

function TestSwitch:test_switch_chip()
    local db = construct_db()
    local chip = sw_chip.new(db)
    chip:add_object({Type = 1, Unit = 1})
    chip:update_type(1)
    chip:update_type(2)
    chip:add_port({PhysicalId = 1})
    chip:add_vlan({VlanId = 1})
    chip:hard_reset()
    local ok = pcall(chip.soft_reset, chip)
    lu.assertEquals(ok, false)
    ok = pcall(chip.chip_init, chip)
    lu.assertEquals(ok, false)
    chip:update_oem_type()
    ok = pcall(chip.ports_init, chip)
    lu.assertEquals(ok, false)
    ok = pcall(chip.vlan_config, chip)
    lu.assertEquals(ok, false)
    ok = pcall(chip.vlans_init, chip)
    lu.assertEquals(ok, false)
    chip:try_trigger_alarm()
    chip:try_remove_alarm()
    ok = pcall(chip.start_init, chip)
    lu.assertEquals(ok, false)
end